package com.market.sys.api.client;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.market.sys.common.Result;
import com.market.sys.entity.*;
import com.market.sys.service.*;
import com.market.sys.util.TimeUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author xd
 * @since 2024-03-26
 */
@RestController
@RequestMapping("/sys/contract")
public class ContractController {

    @Resource
    private IContractService contractService;

    @Resource
    private IUserService userService;

    @Resource
    private INotificationService notificationService;

    @Resource
    private IBoothService boothService;

    @Resource
    private IProvinceService provinceService;

    @Resource
    private ICityService cityService;

    @Resource
    private ICountyService countyService;

    @Resource
    private IStreetService streetService;


    @PostMapping("/fetchContractByUserId")
    public Result<?> fetchContractByUserId(@RequestBody Map<String, Object> paramMap){
        try {
            String userRole = String.valueOf(paramMap.get("userRole"));
            String userId = String.valueOf(paramMap.get("userId"));
            List<Map<String, Object>> mapList = new ArrayList<>();
            List<Contract> contractList;
            if ("0".equals(userRole)){
                contractList = contractService.query().eq("a_id", userId).list();
            }else {
                contractList = contractService.query().eq("b_id", userId).list();
            }
            for (Contract contract : contractList) {
                Booth booth = boothService.query().eq("id", contract.getBoothId()).one();
                Map<String, Object> map = new HashMap<>();
                map.put("contract",contract);
                map.put("tanzhu", userService.query().eq("id", contract.getAId()).one());
                map.put("user", userService.query().eq("id", contract.getBId()).one());
                map.put("booth", booth);
                map.put("needPay",getNeedPay(booth.getLocation(), booth, contract));
                mapList.add(map);
            }
            return Result.success(mapList);
        }catch (Exception e){
            return Result.error("系统繁忙，查询失败");
        }
    }


    @PostMapping("/deleteContract")
    public Result<?> deleteContract(@RequestBody Map<String, Object> paramMap){
        if (contractService.remove(new LambdaQueryWrapper<Contract>().eq(Contract::getId,paramMap.get("id")))){
            return Result.success("取消申请成功");
        }else {
            return Result.error("取消申请失败");
        }
    }

    /**
     * 租户支付
     * @param paramMap
     * @return
     */
    @PostMapping("/zhifu")
    public Result<?> zhifu(@RequestBody Map<String, Object> paramMap){
        try {
            String notificationId = String.valueOf(paramMap.get("notificationId"));
            String boothId = String.valueOf(paramMap.get("boothId"));
            Booth booth = boothService.lambdaQuery().eq(Booth::getId, boothId).one();
            String tanzhuId  = String.valueOf(booth.getUserId());
            String userId = String.valueOf(paramMap.get("userId"));
            notificationService.update().set("state", 1).eq("id", notificationId).update();
            notificationService.createNotification("对方已缴纳第一月费用",
                    "",
                    Integer.valueOf(tanzhuId),
                    Integer.valueOf(userId),
                    Integer.valueOf(boothId), "摊位", 1);
            return Result.success("支付成功");
        }catch (Exception e){
            e.printStackTrace();
           return Result.error("服务器异常，支付失败");
        }
    }

    @PostMapping("/agreeOrReject")
    public Result<?> agreeOrReject(@RequestBody Map<String, Object> paramMap){
        String operatorInfo = String.valueOf(paramMap.get("operatorInfo"));
        String boothId = String.valueOf(paramMap.get("boothId"));
        String userId = String.valueOf(paramMap.get("userId"));
        String tanzhuId = String.valueOf(paramMap.get("tanzhuId"));
        String contractId = String.valueOf(paramMap.get("contractId"));
        String notificationId = String.valueOf(paramMap.get("notificationId"));
        notificationService.update().set("state", 1).eq("id", notificationId).update();
        if ("agree".equals(operatorInfo)){
            // 修改摊位状态
            boothService.update().set("state",2).eq("id",boothId).update();
            Booth booth = boothService.query().eq("id", boothId).one();
            notificationService.createNotification("摊主同意了您对"+booth.getBoothName()+"的申请",
                    "请立即支付第一月的租金",
                    Integer.valueOf(userId),
                    Integer.valueOf(tanzhuId),
                    Integer.valueOf(boothId), "摊位", 0);
        }else {
            Booth booth = boothService.query().eq("id", boothId).one();
            notificationService.createNotification("摊主拒绝了您对"+booth.getBoothName()+"的申请",
                    "摊主拒绝了您的申请",
                    Integer.valueOf(userId),
                    Integer.valueOf(tanzhuId),
                    Integer.valueOf(boothId), "摊位", 1);
            contractService.remove(new LambdaQueryWrapper<Contract>().eq(Contract::getId, contractId));
        }

        return Result.success("操作成功");
    }


    @PostMapping("/AUserConfirmInfo")
    public Result<?> AUserConfirmInfo(@RequestBody Map<String, Object> paramMap){
        String contractId = String.valueOf(paramMap.get("id"));
        String AName = String.valueOf(paramMap.get("AName"));
        String APhone = String.valueOf(paramMap.get("APhone"));
        String AID = String.valueOf(paramMap.get("AID"));
        String ATime = TimeUtil.timeYmd(new Date());
        String boothName = String.valueOf(paramMap.get("boothName"));

        boolean update = contractService.update().set("a_name", AName).set("a_phone", APhone).set("a_sign_date", ATime).set("a_id", AID)
                .set("title",boothName+"的合同").eq("id", contractId).update();

        if (update){
            return Result.success("确认信息成功");
        }else {
            return Result.error("确认信息失败");
        }
    }

    /**
     * 租户继续申请，并且已经填好了手机号，姓名
     * @param paramMap 参数map
     * @return 是否申请成功
     */
    @PostMapping("/BUserContinueApply")
    public Result<?> BUserContinueApply(@RequestBody Map<String, Object> paramMap){
        String remark = String.valueOf(paramMap.get("remark"));
        String contractId = String.valueOf(paramMap.get("id"));
        String boothId = String.valueOf(paramMap.get("boothId"));
        String BName = String.valueOf(paramMap.get("BName"));
        String BPhone = String.valueOf(paramMap.get("BPhone"));
        String BID = String.valueOf(paramMap.get("BID"));
        String BTime = TimeUtil.timeYmd(new Date());

        boolean update = contractService.update().set("b_name", BName).set("b_phone", BPhone).set("b_sign_date", BTime).set("b_id", BID)
                .eq("id", contractId).update();

        User senderUser = userService.query().eq("id", BID).one();
        Booth booth = boothService.query().eq("id", boothId).one();
        notificationService.createNotification(senderUser.getNickName()+
                        "申请了您的摊位："
                        +booth.getBoothName(),
                "该申请人的留言："+remark, booth.getUserId(), Integer.valueOf(BID), Integer.valueOf(boothId), "摊位", 0);

        if (update){
            return Result.success("申请成功");
        }else {
            return Result.error("申请失败");
        }
    }

    @PostMapping("/create")
    public Result<?> createContract(@RequestBody Map<String, Object> paramMap) {
        Contract contract = BeanUtil.fillBeanWithMap(paramMap, new Contract(), false);
        if (BeanUtil.isEmpty(contract)) {
            return Result.error("请输入合同信息");
        }

        BigDecimal needPay = null;
        Booth booth = boothService.query().eq("id", contract.getBoothId()).one();
        contract.setTitle(booth.getBoothName()+"的将合同");
        String location = (String) paramMap.get("location");
        if (!location.contains("-")) {
            // 如果不包含 “-” 符号，则证明是申请的省的摊位
            Province province = provinceService.query().eq("province_name", location).one();
            needPay = ((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee())).multiply(province.getLevel());
            needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
        } else {
            // 包含 “-”，则分割
            String[] locationSplits = location.split("-");
            if (locationSplits.length == 4) {
                // 长度是四的话，就证明是街道
                Street street = streetService.query().eq("street_name", locationSplits[3]).one();
                County county = countyService.query().eq("id", street.getCountyId()).one();
                var city = cityService.query().eq("id", county.getCityId()).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();
                BigDecimal countyLevel = county.getLevel();
                BigDecimal streetLevel = street.getLevel();

                needPay = (((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel)).multiply(countyLevel)).multiply(streetLevel);
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            } else if (locationSplits.length == 3) {
                County county = countyService.query().eq("county_name", locationSplits[2]).one();
                City city = cityService.query().eq("id", county.getCityId()).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();
                BigDecimal countyLevel = county.getLevel();

                needPay = (((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel)).multiply(countyLevel));
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            } else if (locationSplits.length == 2) {
                City city = cityService.query().eq("city_name", locationSplits[1]).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();

                needPay = ((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel));
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            }
        }

        Map<String, Object> map = new HashMap<>(2);
        contract.setStartDate(TimeUtil.timeYmd(new Date()));

        // 初始日期
        String initialDateStr = TimeUtil.timeYmd(new Date());
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;

        // 解析初始日期
        LocalDate initialDate = LocalDate.parse(initialDateStr, formatter);

        // 添加租期到初始日期
        LocalDate endDate = initialDate.plusMonths(contract.getRentalTerm());

        // 设置结束日期
        contract.setEndDate(endDate.format(formatter));
        if (contractService.save(contract)) {
            contract = contractService.query().orderByDesc("id").list().get(0);
            map.put("needPay", needPay);
            map.put("contract", contract);
            return Result.success(map);
        } else {
            return Result.error("系统繁忙，生成合同失败");
        }
    }

    public BigDecimal getNeedPay(String location, Booth booth, Contract contract){
        BigDecimal needPay = null;
        if (!location.contains("-")) {
            // 如果不包含 “-” 符号，则证明是申请的省的摊位
            Province province = provinceService.query().eq("province_name", location).one();
            needPay = ((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee())).multiply(province.getLevel());
            needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
        } else {
            // 包含 “-”，则分割
            String[] locationSplits = location.split("-");
            if (locationSplits.length == 4) {
                // 长度是四的话，就证明是街道
                Street street = streetService.query().eq("street_name", locationSplits[3]).one();
                County county = countyService.query().eq("id", street.getCountyId()).one();
                var city = cityService.query().eq("id", county.getCityId()).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();
                BigDecimal countyLevel = county.getLevel();
                BigDecimal streetLevel = street.getLevel();

                needPay = (((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel)).multiply(countyLevel)).multiply(streetLevel);
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            } else if (locationSplits.length == 3) {
                County county = countyService.query().eq("county_name", locationSplits[2]).one();
                City city = cityService.query().eq("id", county.getCityId()).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();
                BigDecimal countyLevel = county.getLevel();

                needPay = (((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel)).multiply(countyLevel));
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            } else if (locationSplits.length == 2) {
                City city = cityService.query().eq("city_name", locationSplits[1]).one();
                Province province = provinceService.query().eq("id", city.getProvinceId()).one();

                BigDecimal provinceLevel = province.getLevel();
                BigDecimal cityLevel = city.getLevel();

                needPay = ((((booth.getRentalFee().multiply(booth.getArea())).add(booth.getExtraFee()))
                        .multiply(provinceLevel))
                        .multiply(cityLevel));
                needPay = needPay.multiply(BigDecimal.valueOf(contract.getRentalTerm()));
            }
        }

        return needPay;
    }
}
